import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import { localRoutes } from './localRoutes'
import { resetRouters, routerHandler } from './routerHandler'
import { useNprogress } from '@/hooks/useNprogress'
import { useUserStore } from '@/stores/user'
import { useThemeStore } from '@/stores/theme'
import { useMenuStore } from '@/stores/menu'

/**
 * 路由模式
 * @description 根据 env.VITE_APP_ROUTER_MODE 配置
 */
const routerMode = () => {
  if (import.meta.env.VITE_APP_ROUTER_MODE === 'history') {
    return createWebHistory(import.meta.env.VITE_APP_BASE)
  } else {
    return createWebHashHistory()
  }
}

/**
 * 路由实例
 */
const router = createRouter({
  history: routerMode(),
  routes: localRoutes,
  scrollBehavior: () => ({ left: 0, top: 0 }),
})

/**
 * 路由白名单
 * @description 此处白名单列表，以及路由meta.open为true，皆为开放页
 */
const whiteList = ['/login']

/**
 * 路由守卫
 */
router.beforeEach(async (to, from) => {
  // console.log('to from :>> ', to, from)

  const userStore = useUserStore()
  const menuStore = useMenuStore()
  const themeStore = useThemeStore()

  // 进度条开始
  useNprogress().start()

  // 动态标题设置
  if (themeStore.isDynamicTitle && !!to.meta.title) {
    document.title = `${to.meta.title} - ${WEB_CONFIG.title}`
  } else {
    document.title = WEB_CONFIG.title
  }

  // token鉴权
  if (userStore.token) {
    // 有token时，访问登录页时不跳转登录，而是停留在当前页
    if (to.path == '/login') return from.fullPath
    // 有token时，必须后置白名单访问
    if (whiteList.includes(to.path)) return true
  } else {
    // 无token时，必须前置白名单访问
    if (whiteList.includes(to.path)) return true
    // 无token时，需要重置路由并跳转登录
    resetRouters()
    return { path: '/login', replace: true }
  }

  // 如果没有菜单列表，就重新请求菜单列表并添加动态路由
  if (!menuStore.allRoutesFlat.length) {
    // 路由处理
    await routerHandler()
    return { ...to, replace: true }
  }

  return
})

/**
 * 路由跳转错误
 */
router.onError((error) => {
  useNprogress().done()
  console.warn('路由跳转错误 ==>', error.message)
})

/**
 * 路由跳转结束
 */
router.afterEach(() => {
  useNprogress().done()
})

export default router
